package com.example.accessdemo.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.thread.ThreadFactoryBuilder;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;

/**
 * @ClassName MySyncTest
 * @Description TODO
 * @Author kuangdda
 * @Date 16:47 2023/1/6
 * @Version 1.0
 **/
@Service
public class MyThreadService {
    
    @Resource
    private ThreadPoolExecutor testDynamicExecutor;

    /**
     * 通过自己维护线程池来进行多线程处理
     * @param list
     * @param nThread
     * @param resultList
     * @return
     * @param <T>
     */
    @Async
    public <T> Future<Boolean> sysThread(List<T> list, int nThread, List<Map<String,Object>> resultList){
        if(CollUtil.isEmpty(list) || nThread <= 0 || CollUtil.isEmpty(list)){
            return new AsyncResult<>(true);
        }

        /**
         * 定义线程执行的计数器
         */
        CountDownLatch countDownLatch = new CountDownLatch(list.size());

        Semaphore semaphore = new Semaphore(nThread);

        ThreadFactory threadFactory = new ThreadFactoryBuilder().build();

        ExecutorService pool = new ThreadPoolExecutor(
                5,
                200,
                0l,
                TimeUnit.MILLISECONDS,
                new LinkedBlockingDeque<>(1024),
                threadFactory,
                new ThreadPoolExecutor.AbortPolicy());
        for (T l: list){
            try {
                semaphore.acquire();
                pool.execute(()->{
                    HashMap<String,Object> stringObjectHashMap = new HashMap<>();
                    stringObjectHashMap.put("key",l);
                    stringObjectHashMap.put("value", l);
                    resultList.add(stringObjectHashMap);
                    semaphore.release();
                    /**
                     * 通过计数器递减来判断所有子线程是否执行完毕
                     */
                    countDownLatch.countDown();
                });
            }catch (InterruptedException e){

            }
        }

        try {
            /**
             * 等待所有线程都执行完毕后关闭线程池
             */
            countDownLatch.await();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } finally {
            pool.shutdown();
        }

        return new AsyncResult<>(Boolean.TRUE);
    }
    
    /**
     * 通过hippo4j统一维护线程池进行多线程处理
     * @param list
     * @param resultList
     * @return
     * @param <T>
     */
    @Async
    public <T> Future<Boolean> sysThread(List<T> list, List<Map<String,Object>> resultList){
        if(CollUtil.isEmpty(list) || CollUtil.isEmpty(list)){
            return new AsyncResult<>(true);
        }
        
        /**
         * 定义线程执行的计数器
         */
        CountDownLatch countDownLatch = new CountDownLatch(list.size());
        
        for (T l: list){
            testDynamicExecutor.execute(()->{
                HashMap<String,Object> stringObjectHashMap = new HashMap<>();
                stringObjectHashMap.put("key",l);
                stringObjectHashMap.put("value", l);
                resultList.add(stringObjectHashMap);
                /**
                 * 通过计数器递减来判断所有子线程是否执行完毕
                 */
                countDownLatch.countDown();
            });
        }
        
        try {
            /**
             * 等待所有线程都执行完毕后关闭线程池
             */
            countDownLatch.await();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        
        return new AsyncResult<>(Boolean.TRUE);
    }
}
